package com.doyutu.seed.config.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.doyutu.seed.entity.StatRole;
import com.doyutu.seed.entity.StatUser;
import com.doyutu.seed.entity.StatUserRoleRel;
import com.doyutu.seed.service.StatRoleService;
import com.doyutu.seed.service.StatUserRoleRelService;
import com.doyutu.seed.service.StatUserService;
import java.util.HashSet;
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author DoyuTu
 * @version 0.0.1
 * spring-boot-project-seed
 */
@Component
public class LoginRealm extends AuthorizingRealm {

    @Autowired
    private StatUserService statUserService;

    @Autowired
    private StatRoleService statRoleService;

    @Autowired
    private StatUserRoleRelService statUserRoleRelService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获得签名, 可做进一步查询
//        User user = (User) principalCollection.getPrimaryPrincipal();
//
//        Set<String> set = new HashSet<>();
//        set.add("admin");

        StatUser statUser = (StatUser) principalCollection.getPrimaryPrincipal();
        Set<String> sets = getRolesById(statUser.getId());
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(sets);
        return simpleAuthorizationInfo;
    }

    private Set<String> getRolesById(Long id) {
        Set<String> sets = new HashSet<>(1);
        StatUserRoleRel statUserRoles = statUserRoleRelService.getOne(new QueryWrapper<>(StatUserRoleRel.builder()
                .userId(id)
                .build()));
        StatRole statRole = statRoleService.getOne(new QueryWrapper<>(StatRole.builder()
                .id(statUserRoles.getRoleId())
                .build()));
        sets.add(statRole.getName());
        return sets;
    }

    /**
     * 登陆认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 1.从主体认证信息中获取用户名
        String userName = authenticationToken.getPrincipal().toString();
        StatUser statUser = getStatUser(userName);
        if (statUser == null || statUser.getPassword() == null) {
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(statUser, statUser.getPassword(), getName());
        // 加密 salt
//        simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(""));
        return simpleAuthenticationInfo;
    }

    private StatUser getStatUser(String userName) {
        StatUser entity = StatUser.builder()
                .username(userName)
                .build();
        return statUserService.getOne(new QueryWrapper<>(entity));
    }
}
